package org.finalministry.gui.tests;

import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;

import org.finalministry.database.connection.FinalministryDatabaseConnection;
import org.finalministry.database.dao.DaoFactory;
import org.finalministry.objects.Contact;
import org.finalministry.objects.Territory;
import org.geotools.geometry.jts.Geometries;
import org.geotools.geometry.jts.LiteShape;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.WKTReader;

/**
 * Example how to draw polygons and points
 * <p>
 * TODO: create access to DB and represents all territories with contacts ...
 * maybe even save them as png
 * 
 * @author admin
 * 
 */
public class JTSDrawingPanel extends JPanel {

	private static final long serialVersionUID = 4513287920700612637L;

	private static final int MARGIN = 10;

	private List<Geometry> geometries = new ArrayList<Geometry>();
	private AffineTransform geomToScreen;

	public void addGeometry(Geometry geom) {
		geometries.add(geom);
	}

	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);

		if (!geometries.isEmpty()) {
			setTransform();

			Graphics2D g2d = (Graphics2D) g;
			Paint polyPaint = new GradientPaint(0, 0, Color.CYAN, 100, 100, Color.MAGENTA, true);
			Paint defaultPaint = Color.BLUE;

			for (Geometry geom : geometries) {
				LiteShape shape = new LiteShape(geom, geomToScreen, false);

				Coordinate c = getTransformedCoordinatesFromGeometry(geom);

				if (Geometries.get(geom) == Geometries.POLYGON) {
					// g2d.setPaint(polyPaint);
					g2d.setColor(Color.BLUE);
					g2d.fill(shape);
				} else if (Geometries.get(geom) == Geometries.POINT) {
					g2d.setColor(Color.RED);

					int x = (int) Math.round(c.x);
					int y = (int) Math.round(c.y);

					System.out.println("X = " + x);
					g2d.fillRect(x - 2, y - 2, 4, 4);
				} else {
					g2d.setPaint(defaultPaint);

					g2d.setColor(Color.RED);
					g2d.draw(shape);
				}
			}
		}
	}

	/**
	 * My own function transforming coordinates to graphically representable 2D
	 * points
	 * 
	 * @param geometry
	 * @return
	 */
	public Coordinate getTransformedCoordinatesFromGeometry(Geometry geometry) {
		Coordinate coordinates = geometry.getEnvelope().getCoordinates()[0];

		Point2D[] ptSrc = { new Point2D.Double(coordinates.x, coordinates.y) };
		Point2D[] ptDest = { new Point2D.Double() };

		geomToScreen.transform(ptSrc, 0, ptDest, 0, 1);

		Coordinate newCoordinates = new Coordinate(ptDest[0].getX(), ptDest[0].getY());
		return newCoordinates;
	}

	private void setTransform() {
		Envelope env = getGeometryBounds();
		Rectangle visRect = getVisibleRect();
		Rectangle drawingRect = new Rectangle(visRect.x + MARGIN, visRect.y + MARGIN, visRect.width - 2 * MARGIN, visRect.height - 2 * MARGIN);

		double scale = Math.min(drawingRect.getWidth() / env.getWidth(), drawingRect.getHeight() / env.getHeight());
		double xoff = MARGIN - scale * env.getMinX();
		double yoff = MARGIN + env.getMaxY() * scale;
		geomToScreen = new AffineTransform(scale, 0, 0, -scale, xoff, yoff);
	}

	private Envelope getGeometryBounds() {
		Envelope env = new Envelope();
		for (Geometry geom : geometries) {
			Envelope geomEnv = geom.getEnvelopeInternal();
			env.expandToInclude(geomEnv);
		}

		return env;
	}

	public static void main(String[] args) throws Exception {
		JTSDrawingPanel panel = new JTSDrawingPanel();
		JFrame frame = new JFrame("Draw geometries");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		WKTReader reader = new WKTReader();

		DaoFactory.setFinalMinistryConnection(new FinalministryDatabaseConnection("finalministryTest", "sa", "sa", 7786));

		List<Territory> territories = DaoFactory.getInstance().getTerritoryDAO().getAll();

		for (Territory territory : territories) {

			panel.addGeometry(territory.getArea().getGeometry());
		}

		List<Contact> contactList = DaoFactory.getInstance().getContactDAO().getAll();

		for (Contact contact : contactList) {
			System.out.println(contact.getLastName());
			panel.addGeometry(contact.getAddress().getCoordinate());
		}

		frame.add(panel);
		frame.setSize(500, 500);

		frame.setVisible(true);

	}
}